#pragma once
#include <map>
#include <QMutex>
#include <QString>
using namespace std;


class CHBMutexFactory;

class CHBMutexFactoryAutoLocker
{
public:
	CHBMutexFactoryAutoLocker(CHBMutexFactory& mutexFactory, const QString& sMutexName);
	~CHBMutexFactoryAutoLocker();

private:
	CHBMutexFactory&	m_mutexFactory;
	QString				m_sMutexName;
};

class CHBMutexFactory
{
public:
	CHBMutexFactory(void);
	~CHBMutexFactory(void);

public:
	void Lock(const QString& sMutexName);
	void UnLock(const QString& sMutexName);

private:
	QMutex*	_getMutexPtr(const QString& sMutexName);

private:
	std::map<QString, QMutex*>	m_mutexMap;
	QMutex						m_mutex;
};

class CHBMutexFactorySingleton
{
private:
	CHBMutexFactorySingleton();
	~CHBMutexFactorySingleton();

public:
	static CHBMutexFactorySingleton& instance();

public:
	CHBMutexFactory& GetMutexFactory() { return m_mutexFactory; }

private:
	CHBMutexFactory				m_mutexFactory;
	static QMutex				m_mutex;
};

#define g_AutoLockerMutex(mutexName) CHBMutexFactoryAutoLocker hbMutexFactoryAutoLocker(CHBMutexFactorySingleton::instance().GetMutexFactory(), mutexName)
#define g_LockMutex(mutexName) CHBMutexFactorySingleton::instance().GetMutexFactory().Lock(mutexName)
#define g_UnLockMutex(mutexName) CHBMutexFactorySingleton::instance().GetMutexFactory().UnLock(mutexName)
